/* =============================================================
 * array-utils.js v1.1.0
 * =============================================================
 * Original written by Ysy
 * =============================================================
 * Date 15/06/2021
 * ============================================================ */
import CommonUtils from "@/utils/common-utils";
import NumberUtils from "@/utils/number-utils";
import StringUtils from "@/utils/string-utils";

export default class ArrayUtils {
  /**
   * @Author Ysy
   * @Description // 数组判空
   * @Date 11:14 2021/8/19
   * @param array
   **/
  static isEmpty(array) {
    let boolean = false;

    if (!array || Object.is(Object.keys(array).length, 0)) boolean = true;

    return boolean;
  }

  /**
   * @Author Ysy
   * @Description // 单一数组去重  ["1","2","2","3"]
   * @Date 11:14 2021/8/19
   * @param array
   **/
  static noRepeatSingle(array) {
    if (!CommonUtils.isArray(array)) return [];

    return Array.from(new Set(array));
  }

  /**
   * @Author Ysy
   * @Description // 数组按某一属性分组
   * @Date 11:14 2021/8/19
   * @param array
   * @param key
   **/
  static groupBy(array, key) {
    // key:数组对象中的属性 此方法返回值是一个对象
    if (!CommonUtils.isArray(array)) return [];

    let group = array.reduce((acc, cur) => {
      (acc[cur[key]] = acc[cur[key]] || []).push(cur);
      return acc;
    }, {});
    // 整理成数组
    let arr = [];
    Object.keys(group).forEach((key) => {
      arr.push({
        key: key,
        list: group[key],
      });
    });

    return arr;
  }

  /**
   * @Author Ysy
   * @Description // 数组 按照某一属性求和
   * @Date 11:14 2021/8/19
   * @param array
   * @param key
   **/
  static sumByKey(array, key) {
    if (!CommonUtils.isArray(array)) return [];

    return array.reduce((acc, cur, idx, src) => {
      // acc:上一次调用回调时返回的累积值  cur:正在处理的元素  idx:正在处理的当前元素的索引  src:源数组(原数组)
      return NumberUtils.addition(acc, cur[key]);
    }, 0);
  }

  /**
   * @Author Ysy
   * @Description // 多维数组转一维数组
   * @Date 11:14 2021/8/19
   * @param array
   **/
  static transferOneArray(array) {
    // let arr = [[0, 1], [2, 3], [4,[5,6,7]]]
    if (!Array.isArray(array)) return [];

    return array.reduce(
      (acc, cur) =>
        acc.concat(Array.isArray(cur) ? this.transferOneArray(cur) : cur),
      []
    );
  }

  /**
   * @Author Ysy
   * @Description // 记录数组中元素重复次数
   * @Date 11:14 2021/8/19
   * @param array
   **/
  static countEleRepeatTime(array) {
    // let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
    return array.reduce((acc, cur) => {
      if (cur in acc) {
        acc[cur]++;
      } else {
        acc[cur] = 1;
      }
      return acc;
    }, {});
  }

  /**
   * @Author Ysy
   * @Description // 按照汉字和首字母分组
   * @Date 11:14 2021/8/19
   * @param arr
   **/
  static groupByCharacters(arr) {
    // 数据格式  let items = [{id: "1",name: "安吉",}, {id: "2",name: "安庆",}, {id: "3",name: "大连",}, {id: "4",name: "上海",}, {id: "5",name: "北京",}];
    if (!String.prototype.localeCompare) return null;

    let letters = "*abcdefghjklmnopqrstwxyz".split("");
    let zh = "阿八嚓哒妸发旮哈讥咔垃痳拏噢妑七呥扨它穵夕丫帀".split("");

    let segs = [];
    let curr;
    letters.forEach((item, i) => {
      curr = {letter: item, data: []};
      arr.forEach((itm) => {
        if (
          (!zh[i - 1] || zh[i - 1].localeCompare(itm.name) <= 0) &&
          itm.name.localeCompare(zh[i]) === -1
        ) {
          curr.data.push(itm);
        }
      });
      if (curr.data.length) {
        segs.push(curr);
        curr.data.sort(function (a, b) {
          return a.name.localeCompare(b.name);
        });
      }
    });
    return segs;
  }

  /**
   * @Author Ysy
   * @Description // 按照汉字顺序排序
   * @Date 11:14 2021/8/19
   * @param array
   **/
  static orderByCharacters(array) {
    return array.sort( function ( a, b ) {
      return a.name.localeCompare( b.name, "zh" );
    } );
  }

  /**
   * @Author Ysy
   * @Description // 按照数字顺序排序
   * @Date 11:14 2021/8/19
   * @param array
   * @param key
   * @param mode
   **/
  static orderByNumber(array, key, mode) {
    // key：数组中对象的属性  mode：up-升序  down-降序
    mode = mode ? mode : "up";
    return array.sort( ( a, b ) => {
      if ( StringUtils.equals( "up", mode ) ) {
        return a[ key ] - b[ key ];
      } else {
        return b[ key ] - a[ key ];
      }
    } );
  }

  /**
   * @Author Ysy
   * @Description // 提取数组中的相同value值的元素
   * 从 ['aaa','bbb','ccc']、[{code: 1, name: 'ddd'}, {code: 2, name: 'aaa'}]  ==>  ["aaa"]
   * getSameValues(array1,array2,null,'name')
   * @Date 11:14 2021/8/19
   * @param array1
   * @param array2
   * @param key1
   * @param key2
   **/
  static getSameValues(array1, array2, key1, key2) {// key1 如果array1数组元素为对象  key1 对象的key
    if (!CommonUtils.isArray(array1) || !CommonUtils.isArray(array2)) return [];

    return array1.reduce((acc, cur, idx, arr) => {
      let find = array2.find(obj2 => {
        let object1 = key1 ? cur[key1] : cur;
        let object2 = key2 ? obj2[key2] : obj2;

        if (Object.is(object1, object2)) return object2;
      });

      if (CommonUtils.isObject(find)) {
        acc.push(find[key2]);
      } else if (CommonUtils.isString(find)) {
        acc.push(find);
      } else {
      }

      return acc;
    }, []);
  }

  /**
   * 两个对象数据根据某一属性排重
   * @param array1
   * @param array2
   * @param key
   * @returns {*[]|*}
   */
  static noRepeatForObjListByKey(array1, array2, key) {
    if (!CommonUtils.isArray(array1) || !CommonUtils.isArray(array2)) return [];

    return array1.reduce((acc, cur, idx, arr) => {
      let find = array2.find(obj2 => cur[key] === obj2[key]);

      find && acc.push(find[key]);

      return acc;
    }, []);
  }
};
